From e9dc7fc7c0eab51f8242fc0235bb9fccc71ce392 Mon Sep 17 00:00:00 2001 From: robertlipe Date: Sun, 15 Sep 2013 18:44:12 +0000 Subject: [PATCH] More pulling at removing C strings internally: unicsv_print_str and strenquote. A victim of this is the seemingly unused sportsim format. It was doing stupid things in the format definition with high byte characters and unclear encodings. After a few hours trying to save it, I just chopped it. --- gpsbabel/csv_util.cc | 51 +++++++------------ gpsbabel/defs.h | 2 +- .../style/{ => deprecated}/sportsim.style | 0 .../testo.d/{ => deprecated}/sportsim.test | 0 gpsbabel/unicsv.cc | 51 ++++++------------- gpsbabel/util.cc | 44 +++++----------- gpsbabel/xcsv_tokens.gperf | 2 +- gpsbabel/xol.cc | 5 +- 8 files changed, 51 insertions(+), 104 deletions(-) rename gpsbabel/style/{ => deprecated}/sportsim.style (100%) rename gpsbabel/testo.d/{ => deprecated}/sportsim.test (100%) diff --git a/gpsbabel/csv_util.cc b/gpsbabel/csv_util.cc index 246cb1f59..a09c577a0 100644 --- a/gpsbabel/csv_util.cc +++ b/gpsbabel/csv_util.cc @@ -1531,7 +1531,6 @@ xcsv_data_read(void) ; } } - } } @@ -2210,7 +2209,7 @@ xcsv_data_write(void) ogue_t* ogp; time_t time; struct tm tm; - char tbuf[32]; +// char tbuf[32]; /* reset the index counter */ waypt_out_count = 0; @@ -2224,44 +2223,30 @@ xcsv_data_write(void) /* output prologue lines, if any. */ QUEUE_FOR_EACH(&xcsv_file.prologue, elem, tmp) { - char* cout, *ctmp; ogp = (ogue_t*) elem; + // If the XCSV description contains weird characters (like sportsim) + // this is where they get lost. + QString cout = ogp->val; - cout = xstrdup((ogp->val) ? ogp->val : ""); + // Don't do potentially expensive replacements if token prefix + // isn't present; + if (cout.contains("__")) { + cout.replace("__FILE__", xcsv_file.fname); + cout.replace("__VERSION__", time == 0 ? "" : gpsbabel_version); - while ((ctmp = strsub(cout, "__FILE__", xcsv_file.fname))) { - xfree(cout); - cout = ctmp; - } + QDateTime dt = QDateTime::fromTime_t(time); + dt = dt.toTimeSpec(Qt::UTC); - while ((ctmp = strsub(cout, "__VERSION__", (time == 0) ? "" : gpsbabel_version))) { - xfree(cout); - cout = ctmp; - } + QString dts = dt.toString("ddd MMM dd hh:mm:ss yyyy"); + cout.replace("__DATE_AND_TIME__", dts); - while (strstr(cout, "__DATE__")) { - strftime(tbuf, sizeof(tbuf), "%m/%d/%Y", &tm); - ctmp = strsub(cout, "__DATE__", tbuf); - xfree(cout); - cout = ctmp; - } + QString d = dt.toString("MM/dd/yyyy"); + cout.replace("__DATE__", d); - while (strstr(cout, "__TIME__")) { - strftime(tbuf, sizeof(tbuf), "%H:%S:%M", &tm); - ctmp = strsub(cout, "__TIME__", tbuf); - xfree(cout); - cout = ctmp; + QString t = dt.toString("hh:mm:ss"); + cout.replace("__TIME__", t); } - - while (strstr(cout, "__DATE_AND_TIME__")) { - strftime(tbuf, sizeof(tbuf), "%a %b %d %H:%M:%S %Y", &tm); - ctmp = strsub(cout, "__DATE_AND_TIME__", tbuf); - xfree(cout); - cout = ctmp; - } - - gbfprintf(xcsv_file.xcsvfp, "%s", cout); - xfree(cout); + gbfprintf(xcsv_file.xcsvfp, "%s", CSTR(cout)); gbfprintf(xcsv_file.xcsvfp, "%s", xcsv_file.record_delimiter); } diff --git a/gpsbabel/defs.h b/gpsbabel/defs.h index cb439da16..020ee1678 100644 --- a/gpsbabel/defs.h +++ b/gpsbabel/defs.h @@ -1028,7 +1028,7 @@ inline int case_ignore_strncmp(const QString& s1, const QString& s2, int n) { int str_match(const char* str, const char* match); int case_ignore_str_match(const char* str, const char* match); -char* strenquote(const char* str, const char quot_char); +QString strenquote(const QString& str, const QChar quot_char); char* strsub(const char* s, const char* search, const char* replace); char* gstrsub(const char* s, const char* search, const char* replace); diff --git a/gpsbabel/style/sportsim.style b/gpsbabel/style/deprecated/sportsim.style similarity index 100% rename from gpsbabel/style/sportsim.style rename to gpsbabel/style/deprecated/sportsim.style diff --git a/gpsbabel/testo.d/sportsim.test b/gpsbabel/testo.d/deprecated/sportsim.test similarity index 100% rename from gpsbabel/testo.d/sportsim.test rename to gpsbabel/testo.d/deprecated/sportsim.test diff --git a/gpsbabel/unicsv.cc b/gpsbabel/unicsv.cc index 31e6ab7e5..5a9813f4b 100644 --- a/gpsbabel/unicsv.cc +++ b/gpsbabel/unicsv.cc @@ -1247,41 +1247,21 @@ unicsv_fatal_outside(const waypoint* wpt) gt_get_mps_grid_longname(unicsv_grid_idx, MYNAME)); } -static void -unicsv_print_str(const char* str) -{ - if (str && *str) { - char* cout, *cx; - - cout = strenquote(str, UNICSV_QUOT_CHAR); - - while ((cx = strstr(cout, "\r\n"))) { - memmove(cx, cx + 1, strlen(cx)); - *cx++ = ','; - lrtrim(cx); - } - while ((cx = strchr(cout, '\r'))) { - *cx++ = ','; - lrtrim(cx); - } - while ((cx = strchr(cout, '\n'))) { - *cx++ = ','; - lrtrim(cx); - } - - gbfprintf(fout, "%s%s", unicsv_fieldsep, cout); - xfree(cout); - } else { - gbfputs(unicsv_fieldsep, fout); - } -} - static void unicsv_print_str(const QString& s) { - char* t = xstrdup(s.toUtf8().data()); - unicsv_print_str(t); - xfree(t); + gbfputs(unicsv_fieldsep, fout); + QString t; + if (!s.isEmpty()) { + t = strenquote(s, UNICSV_QUOT_CHAR); + // I'm not sure these three replacements are necessary; they're just a + // slavish re-implementation of (what I think) the original C code + // was doing. + t.replace("\r\n", ","); + t.replace("\r", ","); + t.replace("\n", ","); + } + gbfputs(t.trimmed(), fout); } #if NEW_STRINGS @@ -1500,16 +1480,15 @@ unicsv_waypt_disp_cb(const waypoint* wpt) break; case grid_lat_lon_dms: { - char* sep, *tmp; + char* sep; + QString tmp; cout = pretty_deg_format(lat, lon, 's', unicsv_fieldsep, 0); sep = strchr(cout, ','); *sep = '\0'; tmp = strenquote(cout, UNICSV_QUOT_CHAR); - gbfprintf(fout, "%s%s", tmp, unicsv_fieldsep); - xfree(tmp); + gbfprintf(fout, "%s%s", CSTR(tmp), unicsv_fieldsep); tmp = strenquote(sep+1, UNICSV_QUOT_CHAR); gbfputs(tmp, fout); - xfree(tmp); } break; diff --git a/gpsbabel/util.cc b/gpsbabel/util.cc index 741d6badb..d78f59869 100644 --- a/gpsbabel/util.cc +++ b/gpsbabel/util.cc @@ -563,36 +563,20 @@ case_ignore_str_match(const char* str, const char* match) return res; } -char* -strenquote(const char* str, const char quot_char) -{ - int len; - const char* cin; - char* cout; - char* tmp; - - if (str == NULL) { - cin = ""; - } else { - cin = (char*)str; - } - - len = strlen(cin); - cout = tmp = (char*) xmalloc((len * 2) + 3); - - *cout++ = quot_char; - while (*cin) { - *cout++ = *cin; - if (*cin++ == quot_char) { - *cout++ = quot_char; - } - } - *cout++ = quot_char; - *cout = '\0'; - - cout = xstrdup(tmp); - xfree(tmp); - return cout; +// for ruote_char = " +// make str = blank into nothing +// make str = foo into "foo" +// make str = foo"bar into "foo""bar" +// No, that doesn't seem obvious to me, either... + +QString +strenquote(const QString& str, const QChar quot_char) +{ + QString replacement = QString("%1%1").arg(quot_char); + QString t = str; + t.replace(quot_char, replacement); + QString r = quot_char + t + quot_char; + return r; } void diff --git a/gpsbabel/xcsv_tokens.gperf b/gpsbabel/xcsv_tokens.gperf index b650d5b75..04301549f 100644 --- a/gpsbabel/xcsv_tokens.gperf +++ b/gpsbabel/xcsv_tokens.gperf @@ -78,7 +78,7 @@ hash (register const char *str, register unsigned int len) 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249 }; - register int hval = len; + register int hval = (int)len; switch (hval) { diff --git a/gpsbabel/xol.cc b/gpsbabel/xol.cc index 4370151e1..7e054628a 100644 --- a/gpsbabel/xol.cc +++ b/gpsbabel/xol.cc @@ -186,9 +186,8 @@ static void xol_write_string(const char* name, const char* str) { if (str && *str) { - char* temp = strenquote(str, '"'); - gbfprintf(fout, " %s=%s", name, temp); - xfree(temp); + QString temp = strenquote(str, '"'); + gbfprintf(fout, " %s=%s", name, CSTR(temp)); } } -- 2.30.2